package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.SMSUtils;
import com.ruoyi.common.core.utils.SmsCodeGenerator;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.service.ISysSmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.Base64;
/**
 * 发送短信验证码服务
 */
@Slf4j
@Service
public class SysSmsServiceImpl implements ISysSmsService {
    @Autowired
    private RedisService redisService;
    /**
     * 发送短信验证码间隔
     */
    @Value("${spring.sms.sendinterval}")
    private long sendInterval;
    @Value("${spring.sms.corpid}")
    private String cropId;
    @Value("${spring.sms.domainurl}")
    private String smsgatewayDomainUrl;
    @Value("${spring.sms.pwd}")
    private String pwd;
    @Value("${spring.sms.content_temp}")
    private String contentTemp;
    @Value("${spring.sms.effective_time}")
    private Long effectiveTime;
    private String decoderContentTemp;
    @Override
    public void sendSmsVerifyCode(String mobile) {
        Map<String, Object> result = new HashMap<>();
        //产生四位随机数
        String validateCode = SmsCodeGenerator.generateSmsCode();
        //验证上次发送时间，防止发送过度频繁
       if(!isCanSendSmsCode(mobile,validateCode))
           throw new ServiceException("发送验证码过于频繁!");
        if(decoderContentTemp==null) {
            // 获取Base64解码器
            Base64.Decoder decoder = Base64.getDecoder();

            // 解码Base64字符串为字节数组
            byte[] decodedBytes = decoder.decode(contentTemp);

            // 将字节数组转换为字符串
            decoderContentTemp = new String(decodedBytes,StandardCharsets.UTF_8);

        }
        //发送短信
        try {
            String sendContent = String.format(decoderContentTemp, validateCode,effectiveTime);
            SMSUtils.sendSMS(cropId, pwd, smsgatewayDomainUrl, mobile, sendContent, "");
        }catch(Exception e) {
            log.error("发送短信验证码失败", e);
            throw new ServiceException("发送短信失败!");
        }
    }

    /**
     * 判断是否能发送短信验证码
     * @param phoneNumber
     * @param validateCode
     * @return
     */
    public  boolean isCanSendSmsCode(String phoneNumber, String validateCode) {
        // 获取上次发送验证码的时间戳
        String lastRequestTimeStr = redisService.getCacheObject(phoneNumber + ":sms:lastRequest");
        if (lastRequestTimeStr != null) {
            long lastRequestTime = Long.parseLong(lastRequestTimeStr);
            long currentTime = System.currentTimeMillis() / 1000; // 当前时间戳（秒）

            // 检查时间间隔
            if (currentTime - lastRequestTime < sendInterval) {
                return false; // 时间间隔不足，不允许发送
            }
        }

        // 更新时间戳
        redisService.setCacheObject(phoneNumber + ":sms:lastRequest", String.valueOf(System.currentTimeMillis() / 1000), sendInterval, TimeUnit.SECONDS);
        // 记录验证码
        redisService.setCacheObject(phoneNumber + ":sms:code", validateCode, effectiveTime, TimeUnit.MINUTES);
        return true; // 允许发送

    }

    /**
     * 验证码是否正确
     * @param mobile 手机号
     * @param code 验证码
     */
    public void verifyCode(String mobile,String code) {
        String cacheCode = redisService.getCacheObject(mobile + ":sms:code");
        if(!code.equals(cacheCode))
            throw new ServiceException("验证码不正确!");
    }
}
